var ByteBuffer = window.dcodeIO.ByteBuffer;

var websockets = [];
var reconnInterval = 10;    //重连间隔
var reconnLock = false;      //避免重复连接
var needconn = true;      //是否需要重连

var lastInteractionTime = 0;//上一次交互时间
var heartbeatTimeout = 60 * 1000;
var heartbeatSendInterval = heartbeatTimeout / 2;

var user = {
    id: "",
    password: "",
    ip: "",
    port: ""
};

var stat = {
    received: 0  //收到次数
    , sent: 0       //发送次数
    , connCount: 0  //连成功次数
    , reconnCount: 0 //重连次数
};

protobuf.load("chat.proto", function (err, root) {
    if (err) {
        throw err;
    }
    loadClass(root);
});

//加载处理消息的JAVA中的class
function loadClass(root) {
    AuthReqBody = root.lookup("com.zfy.im.common.packets.AuthReqBody");
    AuthRespBody = root.lookup("com.zfy.im.common.packets.AuthRespBody");

    JoinReqBody = root.lookup("com.zfy.im.common.packets.JoinReqBody");
    JoinGroupResult = root.lookup("com.zfy.im.common.packets.JoinGroupResult");
    JoinRespBody = root.lookup("com.zfy.im.common.packets.JoinRespBody");

    ChatReqBody = root.lookup("com.zfy.im.common.packets.ChatReqBody");
    ChatRespBody = root.lookup("com.zfy.im.common.packets.ChatRespBody");

    ChatType = root.lookup("com.zfy.im.common.packets.ChatType");
    DeviceType = root.lookup("com.zfy.im.common.packets.DeviceType");
    Command = root.lookup("com.zfy.im.common.packets.Command");

    JoinGroupNotifyBody = root.lookup("com.zfy.im.common.packets.JoinGroupNotifyBody")

}
//初始化websocket
function initWs(url) {
    try {
        //新建socket链接
        // var url = "ws://192.168.80.66:9321";
        var ws = new WebSocket(url);
        //定义二进制编译数组arraybuffer
        ws.binaryType = 'arraybuffer'; // 'blob';//
        //初始化socket监听事件
        /*@param ws websocket
         *@param url ip和端口组成的路径
         */
        initWsEvent(ws, url);
        return ws;
    } catch (e) {
        console.log(e);
        //重连机制
        reconn(url, null, e);
    }
}

function initWsEvent(ws, url) {
    ws.onopen = function (event) {
        var ws = event.srcElement;
        stat.connCount++;
        console.log(ws);
        // var tipele = document.getElementById('tip');
        websockets.push(ws);
        console.log("连接数" + websockets.length);
        lastInteractionTime = new Date().getTime();
        //鉴权命令
        var command = Command.values.COMMAND_AUTH_REQ;
        // var userid = GenNonDuplicateID(10);
        var bodyData = {
            deviceId: "deviceId--888888888888"
            , seq: 1
            , deviceType: DeviceType.DEVICE_TYPE_PC
            , deviceInfo: browser.getVersion()
            , token: user.id
        };

        sendPacket(ws, command, AuthReqBody, bodyData);
    };

    ws.onmessage = function (event) {
        var ws = event.srcElement;
        stat.received++;
        var arrayBuffer = event.data;
        var byteBuffer = ByteBuffer.wrap(arrayBuffer);
        var command = Command.valuesById[byteBuffer.readByte()];
        console.log("收到消息", command, byteBuffer);

        arrayBuffer = byteBuffer.toArrayBuffer();
        // byteBuffer = ByteBuffer.wrap(arrayBuffer);

        var uint8Array = new Uint8Array(arrayBuffer);
        console.log("handle:", handler);
        handler[command].call(handler[command], uint8Array, event, ws);

        lastInteractionTime = new Date().getTime();
    };

    ws.onclose = function (event) {
        var ws = event.srcElement;
        reconn(url, event, null);
    };
    ws.onerror = function (event) {
        var ws = event.srcElement;
        console.log("error", event);
        reconn(url, event, null)
    };
}
function reconn(url, event, e) {
    if (!needconn) {
        console.log("已经不需要重连了", event, e);
        return;
    }

    if (reconnLock) {
        console.log("没有拿到重连权限", event, e);
        return;
    }

    reconnLock = true;
    stat.reconnCount++;

    setTimeout(function () {
        console.log("连接已断开", "正在开始第次" + stat.reconnCount + "重连:" + url, event, e);
        initWs(url);
        reconnLock = false;
    }, reconnInterval);
}


/**
 * 发送packet
 *
 * @param {} ws
 * @param {} command
 * @param {} BodyClass
 * @param {} bodyData
 */
function sendPacket(ws, command, BodyClass, bodyData) {
    var bodyObj = null;
    if (bodyData) {
        bodyObj = BodyClass.create(bodyData);
    }

    var bodyBuffer = null;
    if (bodyObj) {
        bodyBuffer = BodyClass.encode(bodyObj).finish();
    }

    sendBuffer(ws, command, bodyBuffer);
}

/**
 * 发送buffer
 * @param {} ws
 * @param {} command
 * @param {} bodyBuffer
 */
function sendBuffer(ws, command, bodyBuffer) {
    var bodyLength = 0;
    if (bodyBuffer) {
        bodyLength = bodyBuffer.length;
    }

    var allBuffer = ByteBuffer.allocate(1 + bodyLength);
    allBuffer.writeByte(command);

    if (bodyBuffer) {
        allBuffer.append(bodyBuffer);
    }
    //使用连接发送数据
    ws.send(allBuffer.buffer);
    console.log("已经发送", Command.valuesById[command], allBuffer);
    lastInteractionTime = new Date().getTime();
}

/**
 * 发送心跳
 */
function ping() {
    var nowTime = new Date().getTime();
    var iv = nowTime - lastInteractionTime; // 已经多久没发消息了
    if ((heartbeatSendInterval + iv) >= heartbeatTimeout) {
        var command = Command.values.COMMAND_HEARTBEAT_REQ;
        for (var i = 0; i < websockets.length; i++) {
            var ws = websockets[i];
            sendBuffer(ws, command, null);
        }
    }
}
setInterval("ping()", heartbeatSendInterval);


/**
 * 消息处理者
 * @type
 */
var handler = {};
handler.COMMAND_AUTH_RESP = function (uint8Array, event, ws) {
    var respBody = AuthRespBody.decode(uint8Array);
    operate.prototype.loadUsers(respBody.user);//加载用户
    var command = Command.values.COMMAND_JOIN_GROUP_REQ;
    var bodyData = {
        group: "g"
        // group: groupele.value
    };
    sendPacket(ws, command, JoinReqBody, bodyData);
};

handler.COMMAND_JOIN_GROUP_RESP = function (uint8Array, event, ws) {
    var respBody = JoinRespBody.decode(uint8Array);
    console.log("已经进入到群组:" + respBody.group);
};


handler.COMMAND_CHAT_RESP = function (uint8Array, event, ws) {
    var respBody = ChatRespBody.decode(uint8Array);
//	console.log("收到聊天消息:" + stat.received + "-" + respBody.text);
    if (chat.chatRespBodys.length > 200) {
        chat.chatRespBodys = [];
    }

    respBody.date = new Date(respBody.time.toNumber()).format('yyyy-MM-dd hh:mm:ss.S');
    respBody.local = user.id;
    chat.chatRespBodys.push(respBody);
};

handler.COMMAND_JOIN_GROUP_NOTIFY_RESP = function (uint8Array, event, ws) {
    var notifyBody = JoinGroupNotifyBody.decode(uint8Array);
    console.log(notifyBody.userid + "ip地址：" + notifyBody.userip.userip + ":" + notifyBody.userip.port + "进入聊天群" + notifyBody.group);
    if (!isContain(notifyBody.userid, users.chatRoomMembers))
        users.chatRoomMembers.push({userid: notifyBody.userid, userip: notifyBody.userip});

};

handler.COMMAND_EXIT_GROUP_NOTIFY_RESP = function (uint8Array, event, ws) {
    var respBody = ChatRespBody.decode(uint8Array);
    console.log("有人退群了");

};

handler.COMMAND_LOGIN_RESP = function (uint8Array, event, ws) {
    var respBody = ChatRespBody.decode(uint8Array);
    console.log(respBody);
};

var chat = new Vue({
    el: '#chat',
    data: {
        chatRespBodys: []
    }
});

var users = new Vue({
    el: "#members",
    data: {
        chatRoomMembers: []
    }
});

var userNum = new Vue({
    el: "#groupNumbers",
    data: {
        number: users.chatRoomMembers.length
    }
});

var isContain = function (id, users) {
    this.ids = [];

    for (var i = 0, l = users.length; i < l; i++) {
        this.ids.push(users[i].userid);
    }

    for (var j = 0, k = this.ids.length; j < k; j++) {
        if (id == this.ids[j]) return true;
    }

    return false;
};

//判断浏览器类别
var browser = {
    versions: function () {
        var u = navigator.userAgent.toLowerCase();
        // var versions={};
        return {
            chrome: (u.indexOf("applewebkit") > -1),
            ie: (u.indexOf('trident') > -1),
            firefox: u.indexOf('gecko') > -1 && u.indexOf('khml') === -1
        };
    },
    getVersion: function () {
        var version = this.versions();
        if (version.chrome) {
            return "chrome";
        } else if (version.firefox) {
            return "firefox";
        } else if (version.ie) {
            return "ie";
        } else {
            return "unKnow";
        }
    }, getOsInfo: function () {
        var _pf = navigator.platform;
        var _appVersion = navigator.appVersion;
    }
};

function GenNonDuplicateID(randomLength) {
    return Number(Math.random().toString().substr(3, randomLength) + Date.now()).toString(36);
}



